package reci.journal.plugins.search;

import java.io.*;
import java.util.*;

import javax.swing.JOptionPane;

import reci.journal.plugins.Plugin;
import reci.journal.utils.ExtUtil;


/*
 * Copyright (C) 2014 ReciGames
 * See notice in reci.journal.Main.java.
 */

/**
 * Generates and opens an HTML page that links to entries of the form 
 * <journalRoot>/<year>/<year>-<month>-<day>/entry.*
 * By default, assumes plugin's location is <journalRoot>/plugins/Search/
 */
public class Search extends Plugin
{
	private ArrayList<String> matches=new ArrayList<String>();
	
	public Search()
	{
		run();
	}
	
	public static void main(String[] args)
	{
		new Search();
	}
	
	private void run()
	{
		//set default properties
		Properties props=new Properties();
		props.setProperty("templatePath","Search-template.html");
		props.setProperty("journalRootPath","../../");
		props.setProperty("fileRegex","^.*\\.(txt|rtf|html|doc|docx)$");
		props.setProperty("searchRegex",".*");
		
		//load properties from file
		loadSettings(props,"Search.settings","Search settings");
		
		//print properties
		printSettings(props);
		
		//search in journal root
		File file=new File(props.getProperty("journalRootPath"));
		fileRegex=props.getProperty("fileRegex");
		searchRegex=props.getProperty("searchRegex");
		findMatches(file,file.getAbsolutePath().length()+1);
		
		//if found matches
		if(!matches.isEmpty())
		{
			//generate and open HTML page
			String outputPath="Search.html";
			generateHTML(outputPath,props);
			ExtUtil.openFile(outputPath);
		}
		//no matches
		else
		{
			JOptionPane.showMessageDialog(null,"No matches were found.","",JOptionPane.INFORMATION_MESSAGE);
		}
	}
	
	private String fileRegex;
	private String searchRegex;
	
	/**recursively searches dir for matches; trims paths for matches*/
	private void findMatches(File dir, int trimLength)
	{
		File[] files=dir.listFiles();
		
		for(File file : files)
		{
			//if directory
			if(file.isDirectory())
			{
				findMatches(file,trimLength);
			}
			//if file
			else
			{
//				System.out.println(file);
				
				//if matches fileRegex and searchRegex
				if(file.getAbsolutePath().matches(fileRegex))
				{
					System.out.println("matches fileRegex: "+file);
				}
				if(file.getAbsolutePath().matches(fileRegex) && isSearchMatch(file))
				{
					System.out.println(file);
					matches.add(file.toString().replaceAll("\\\\","/"));
				}
			}
		}
	}
	
	/**returns if any line in file matches searchRegex*/
	private boolean isSearchMatch(File file)
	{
		boolean isMatch=false;
		BufferedReader br=null;
		
		try
		{
			br=new BufferedReader(new FileReader(file));
			
			String line;
			while((line=br.readLine())!=null)
			{
				if(line.matches(searchRegex))
				{
					isMatch=true;
					break;
				}
			}
		}
		catch(Exception e)
		{}
		finally
		{
			ExtUtil.close(br);
		}
		
		return isMatch;
	}
	
	/**generates HTML file for viewing matches*/
	private String generateHTML(String htmlPath, Properties props)
	{
		String templatePath=props.getProperty("templatePath");
		
		HashMap<String,String> rules=new HashMap<String,String>();
		rules.put("%m%",getMatchesOutput());//matches
		rules.put("%f%",props.getProperty("fileRegex"));//fileRegex
		rules.put("%s%",props.getProperty("searchRegex"));//searchRegex
		
		return generateHTML(htmlPath,templatePath,rules);
	}
	
	/**returns HTML string with links to matching files*/
	private String getMatchesOutput()
	{
		//example entry:
		//<li><a onclick="call('../2014/2014-04-21/index.html')">2014-04-21</a></li>
		
		final String s0="<li><a onclick=\"call('";
		final String s1="')\">";
		final String s2="</a></li>"+nl;
		
		StringBuffer sb=new StringBuffer();
		
		sb.append("<ul>");
		sb.append(nl);
		
		
		for(String path : matches)
		{
			try
			{
				StringBuffer sb2=new StringBuffer();
				
				System.out.println("match: "+path);
				sb2.append(s0);
				sb2.append(path);//URL to file
				sb2.append(s1);
				
				String[] parts=path.split("/");
				sb2.append(parts[parts.length-2]);//display text
				sb2.append(s2);
				
				sb.append(sb2);
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		
		sb.append("</ul>");
		sb.append(nl);
		
		return sb.toString();
	}
}
